﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.IO;
//using DocumentsTagger.TextMiningUtils;

namespace DocumentsTagger.DM
{
    public delegate void ChangeHandler();
    public class Document
    {
        private readonly String    r_DocumentFileName;
        private readonly String    r_DocumentPath;
        private readonly List<Tag> r_AcceptedTagsList = new List<Tag>();
        private readonly List<Tag> r_SuggestedTagsList = new List<Tag>();
        private readonly List<Tag> r_DeclinedTagsList = new List<Tag>();

        public event ChangeHandler Changed;


        public String FullPath
        { get { return Path.Combine(FilePath, FileName); } }

        public String FileName
        { get { return r_DocumentFileName; } }

        public String FilePath
        { get { return r_DocumentPath; } }

        public String FolderName
        { get { return Path.GetFileName(r_DocumentPath); } }


        public Document(String DocumentFileName, String DocumentPath)
        {
           
            this.r_DocumentFileName = DocumentFileName;
            this.r_DocumentPath = DocumentPath;
        }

        public ReadOnlyCollection<Tag> AcceptedTags
        {
            get
            {
                return this.r_AcceptedTagsList.AsReadOnly();
            }
        }

        public ReadOnlyCollection<Tag> SuggestedTags
        {
            get
            {
                return this.r_SuggestedTagsList.AsReadOnly();
            }
        }

        public ReadOnlyCollection<Tag> DeclinedTags
        {
            get
            {
                return this.r_DeclinedTagsList.AsReadOnly();
            }
        }

        public void AddAcceptedTag(Tag tag)
        {
            if (!this.r_AcceptedTagsList.Contains(tag))
            {
                this.r_AcceptedTagsList.Add(tag);
            }
        }

        public void AddSuggestedTag(Tag tag)
        {
            if (!this.r_SuggestedTagsList.Contains(tag))
            {
                this.r_SuggestedTagsList.Add(tag);
                OnChange();
            }
        }

        public void AddDeclinedTag(Tag tag)
        {
            if (!this.r_DeclinedTagsList.Contains(tag))
            {
                this.r_DeclinedTagsList.Add(tag);
            }
        }

        public override bool Equals(object obj)
        {
            bool isEquals = false;
            Document other = obj as Document;

            if (other != null)
            {
                if ((other.FileName == this.FileName) && (other.FilePath == this.FilePath))
                {
                    isEquals = true;
                }
            }

            return isEquals;
        }

        public override string ToString()
        {
            return String.Format("{0} {1}", this.FilePath, this.FileName);
        }

        public override int GetHashCode()
        {
            return this.r_DocumentFileName.GetHashCode() * 2 *
                   this.r_DocumentPath.GetHashCode() * 3 *
                   this.r_AcceptedTagsList.GetHashCode() * 5 *
                   this.r_SuggestedTagsList.GetHashCode() * 7;
        }

        public DateTime CreationDate { get {return File.GetCreationTime(this.FilePath);}  }
        public long Size { get { return this.getSize(this.FullPath); } }

        private long getSize(string FullPath)
        {
            long fileSize = 0L;

            try
            {
                FileInfo fi = new FileInfo(FullPath);
                fileSize = fi.Length;
                fi = null;
            }
            catch (Exception ex)
            { 
                // do nothing
            }
            return fileSize;
        }

        public void RemoveAcceptedTags(Tag tag)
        {
            r_AcceptedTagsList.Remove(tag);
        }



        public void RemoveDeclinedTags(Tag tag)
        {
            r_DeclinedTagsList.Remove(tag);
        }

        public void RemoveSuggestedTags(Tag tag)
        {
            r_SuggestedTagsList.Remove(tag);
        }

        private void OnChange()
        {
            if (Changed != null)
            {
                Changed();
            }
        }
    }
}
